﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Параметры.Свойство("РежимОткрытияОкна") Тогда
		РежимОткрытияОкна = Параметры.РежимОткрытияОкна
	КонецЕсли;
	
	Параметры.Свойство("РежимДобавления", РежимДобавления);
	
	Параметры.Свойство("РежимВыбора", РежимВыбора);
	Элементы.Классификатор.РежимВыбора = РежимВыбора;
	ЗакрыватьПриВыборе = РежимВыбора;
	
	// Служебные реквизиты
	ПоляКлассификатора = "Код, Наименование, НаименованиеПолное, КодАльфа2, КодАльфа3, УчастникЕАЭС, МеждународноеНаименование";
	
	ПредставлениеОбъектаКлассификатора = ОбщегоНазначения.ПредставлениеОбъекта(Метаданные.Справочники.СтраныМира);
	Если Не ПустаяСтрока(ПредставлениеОбъектаКлассификатора) Тогда
		ПредставлениеОбъектаКлассификатора = " (" + ПредставлениеОбъектаКлассификатора + ")";
	КонецЕсли;
	
	ДанныеКлассификатора = СостояниеКлассификатора();
	Классификатор.Загрузить(ДанныеКлассификатора);
	
	Фильтр = Классификатор.НайтиСтроки(Новый Структура("Код", Параметры.ТекущаяСтрока.Код));
	Если Фильтр.Количество()>0 Тогда
		Элементы.Классификатор.ТекущаяСтрока = Фильтр[0].ПолучитьИдентификатор();
	КонецЕсли;
	
	Элементы.КлассификаторКонтекстноеМенюИзменить.Видимость = ПравоДоступа("Изменение", Метаданные.Справочники.СтраныМира);
	
	ЕстьПравоРедактироватьСтраны = ПравоДоступа("Изменение", Метаданные.Справочники.СтраныМира);
	Элементы.КлассификаторКонтекстноеМенюИзменить.Видимость = ЕстьПравоРедактироватьСтраны;
	Элементы.КлассификаторИзменить.Видимость = ЕстьПравоРедактироватьСтраны;
	Элементы.Классификатор.ТолькоПросмотр = НЕ ЕстьПравоРедактироватьСтраны;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыКлассификатор

&НаКлиенте
Процедура КлассификаторВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	
	Если ВыбраннаяСтрока = Неопределено Или Не ЕстьПравоРедактироватьСтраны Тогда
		Возврат;
	КонецЕсли;

	Если Не РежимВыбора Тогда
		Страна = Классификатор.НайтиПоИдентификатору(ВыбраннаяСтрока);
		
		Если СтраныНетВСпискеСтран(Страна.Наименование) Тогда
			ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Добавить страну ""%1"" из классификатора в список стран мира?'"),
				Страна.Наименование);
			Оповещение = Новый ОписаниеОповещения("ДобавитьСтрану", ЭтотОбъект, ВыбраннаяСтрока);
			ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
		КонецЕсли;
	Иначе
		Если ТипЗнч(ВыбраннаяСтрока) = Тип("Массив") Тогда
			ИдентификаторСтрокиВыбора = ВыбраннаяСтрока[0];
		Иначе
			ИдентификаторСтрокиВыбора = ВыбраннаяСтрока;
		КонецЕсли;
		
		ОповеститьОВыбореЭлементаКлассификатора(ИдентификаторСтрокиВыбора);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьСтрану(Результат, ДополнительныеПараметры) Экспорт

	Если Результат = КодВозвратаДиалога.Да Тогда
		ОповеститьОВыбореЭлементаКлассификатора(ДополнительныеПараметры);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура КлассификаторВыборЗначения(Элемент, Значение, СтандартнаяОбработка)
	ОповеститьОВыбореЭлементаКлассификатора(Значение);
КонецПроцедуры

&НаКлиенте
Процедура КлассификаторПередНачаломИзменения(Элемент, Отказ)
	Отказ = Истина;
	Если ЕстьПравоРедактироватьСтраны Тогда
		ОткрытьФормуЭлементаКлассификатора(Элементы.Классификатор.ТекущиеДанные);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура КлассификаторПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)
	Отказ = Истина;
КонецПроцедуры

&НаКлиенте
Процедура КлассификаторПередУдалением(Элемент, Отказ)
	Отказ = Истина;
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаКлиенте
Процедура ОткрытьФормуЭлементаКлассификатора(ДанныеЗаполнения, ЭтоНовый = Ложь)
	
	Если ДанныеЗаполнения=Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Основание", Новый Структура(ПоляКлассификатора));
	ЗаполнитьЗначенияСвойств(ПараметрыФормы.Основание, ДанныеЗаполнения);
	Если ЭтоНовый Тогда
		ПараметрыФормы.Основание.Вставить("Код", "--");
	Иначе
		ПараметрыФормы.Вставить("ТолькоПросмотр", Истина);
	КонецЕсли;
	ПараметрыФормы.Вставить("Заголовок", ДанныеЗаполнения.Наименование + ПредставлениеОбъектаКлассификатора);
	
	ОткрытьФорму("Справочник.СтраныМира.ФормаОбъекта", ПараметрыФормы, Элементы.Классификатор);
	
КонецПроцедуры

&НаКлиенте
Процедура ОповеститьОВыбореЭлементаКлассификатора(ИдентификаторСтрокиВыбора)
	
	ВсеДанныеСтроки = Классификатор.НайтиПоИдентификатору(ИдентификаторСтрокиВыбора);
	Если ВсеДанныеСтроки <> Неопределено Тогда
		ДанныеСтроки = Новый Структура(ПоляКлассификатора);
		ЗаполнитьЗначенияСвойств(ДанныеСтроки, ВсеДанныеСтроки);
		
		ДанныеВыбора = ДанныеВыбораЭлементаКлассификатора(ДанныеСтроки, ПоляКлассификатора);
		Если ДанныеВыбора.ЭтоНовый Тогда
			ОповеститьОСозданииЭлементов(ДанныеВыбора.Ссылка);
		ИначеЕсли РежимДобавления И ДанныеВыбора.ДанныеОтличаются Тогда
			ДополнительныеПараметры = Новый Структура;
			ДополнительныеПараметры.Вставить("Ссылка", ДанныеВыбора.Ссылка);
			ДополнительныеПараметры.Вставить("Данные", ДанныеСтроки);
			
			Оповещение = Новый ОписаниеОповещения("ПослеВопросаПроОбновление", ЭтотОбъект, ДополнительныеПараметры);
			ПоказатьВопрос(Оповещение, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = '%1 уже присутствует в списке стран. Перезаполнить?'"), ДанныеСтроки.Наименование), РежимДиалогаВопрос.ДаНет);
			Возврат;
		КонецЕсли;
		
		ОповеститьОВыборе(ДанныеВыбора.Ссылка);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Результат - КодВозвратаДиалога
//  ДополнительныеПараметры - Структура:
//   * Ссылка - СправочникСсылка.СтраныМира
//
&НаКлиенте
Процедура ПослеВопросаПроОбновление(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = КодВозвратаДиалога.Да Тогда
		ПерезаполнитьДанныеСтраны(ДополнительныеПараметры);
		Оповестить("Справочник.СтраныМира.Изменение", ДополнительныеПараметры.Ссылка, ЭтотОбъект);
	КонецЕсли;
	Закрыть();
	
КонецПроцедуры

&НаКлиенте
Процедура ОповеститьОСозданииЭлементов(Ссылка)
	ОповеститьОЗаписиНового(Ссылка);
	Оповестить("Справочник.СтраныМира.Изменение", Ссылка, ЭтотОбъект);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ДанныеВыбораЭлементаКлассификатора(Знач СведенияОСтране, ПоляКлассификатора)
	
	Результат = Новый Структура;
	Результат.Вставить("ЭтоНовый",         Ложь);
	Результат.Вставить("Ссылка",           Неопределено);
	Результат.Вставить("Код",              СведенияОСтране.Код);
	Результат.Вставить("ДанныеОтличаются", Ложь);
	
	// Ищем только по коду, так как в классификаторе все коды заданы.
	Ссылка = Справочники.СтраныМира.НайтиПоКоду(СведенияОСтране.Код);
	Результат.ЭтоНовый = Не ЗначениеЗаполнено(Ссылка);
	Если Результат.ЭтоНовый Тогда
		
		Страна = Справочники.СтраныМира.СоздатьЭлемент();
		ЗаполнитьЗначенияСвойств(Страна, СведенияОСтране);
		Страна.Записать();
		Ссылка = Страна.Ссылка;
		
	Иначе
		
		ЗначенияСправочника = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Ссылка, ПоляКлассификатора);
		Для каждого ЗначениеКлассификатора Из СведенияОСтране Цикл
			Если ЗначениеКлассификатора.Значение <> ЗначенияСправочника[ЗначениеКлассификатора.Ключ] Тогда
				Результат.ДанныеОтличаются = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
	Результат.Ссылка = Ссылка;
	
	Возврат Результат;
	
КонецФункции

&НаСервереБезКонтекста
Процедура ПерезаполнитьДанныеСтраны(Знач СведенияОСтране)
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.СтраныМира");
	ЭлементБлокировки.УстановитьЗначение("Ссылка", СведенияОСтране.Ссылка);
	
	НачатьТранзакцию();
	Попытка
		
		Блокировка.Заблокировать();
		Страна = СведенияОСтране.Ссылка.ПолучитьОбъект();
		Если Страна = Неопределено Тогда // объект может быть уже удален в других сеансах
			ОтменитьТранзакцию();
			Возврат;
		КонецЕсли;
		ЗаблокироватьДанныеДляРедактирования(СведенияОСтране.Ссылка);
		
		ЗаполнитьЗначенияСвойств(Страна, СведенияОСтране.Данные);
		Страна.Записать();
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
		
	КонецПопытки;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция СостояниеКлассификатора()
	
	Если Не УправлениеКонтактнойИнформациейСлужебныйПовтИсп.ДоступныМодулиРаботаСАдресами() Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли;
	
	МодульРаботаСАдресами = ОбщегоНазначения.ОбщийМодуль("РаботаСАдресами");
	Данные = МодульРаботаСАдресами.ТаблицаКлассификатора();
	
	Данные.Колонки.Добавить("ИндексПиктограммы", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2, 0)));
	Данные.ЗаполнитьЗначения(8, "ИндексПиктограммы");
	
	Запрос = Новый Запрос("ВЫБРАТЬ Код ИЗ Справочник.СтраныМира ГДЕ Предопределенный");
	Для Каждого СтрокаПредопределенного Из Запрос.Выполнить().Выгрузить() Цикл
		СтрокаДанных = Данные.Найти(СтрокаПредопределенного.Код, "Код");
		Если СтрокаДанных<>Неопределено Тогда
			СтрокаДанных.ИндексПиктограммы = 5;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Данные;
КонецФункции

&НаСервереБезКонтекста
Функция СтраныНетВСпискеСтран(Страна)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ СтраныМира.Ссылка
		|ИЗ Справочник.СтраныМира КАК СтраныМира
		|ГДЕ СтраныМира.Наименование = &Наименование";
	
	Запрос.УстановитьПараметр("Наименование", Страна);
	РезультатЗапроса = Запрос.Выполнить().Выбрать();
	
	Если РезультатЗапроса.Следующий() Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

#КонецОбласти
